package com.deng.config.shiroConfig;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import java.util.LinkedHashMap;
import java.util.Properties;

/**
 * @Author 邓小熙
 * @Date 2022/5/3 9:51
 * @Version 1.0
 *      shiro 的配置类
 */
@Configuration
public class ShiroConfig {
    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(manager);
//        配置登录的url和登录成功的url
        bean.setLoginUrl("/user/login");
        bean.setUnauthorizedUrl("/error/unAuthorized");
//        配置访问权限
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//        /**
//         * 第一部分 前台无权限url  anon:无需认证就可以访问
//         */
        filterChainDefinitionMap.put("/main/**", "anon");//表示可以匿名访问
        filterChainDefinitionMap.put("/error/**", "anon");//表示可以匿名访问
//
//
//        /**
//         * 静态可访问资源
//         */
        filterChainDefinitionMap.put("/Error/*", "anon");
        filterChainDefinitionMap.put("/user/*", "anon");
        filterChainDefinitionMap.put("/home/*", "anon");
        filterChainDefinitionMap.put("/css/*", "anon");
        filterChainDefinitionMap.put("/images/*", "anon");
        filterChainDefinitionMap.put("/edited/*", "anon");

        /**
         * 需要特殊权限的url 如管理员设置
         */

        /**
         * 人员管理
         */
//        filterChainDefinitionMap.put("/user/returnUserManage", "roles[can_manage]");
//        filterChainDefinitionMap.put("/user/admin/updateUserStatus","roles[can_manage]");
        //          专题和专题插入删除
//        filterChainDefinitionMap.put("/column/columnPage", "roles[can_manage]");
//        filterChainDefinitionMap.put("/column/columnPage", "roles[admin]");
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }
    /**
     * 当没有权限时跳转到403unAuthorized.html页面，配置异常后跳转的页面
     * @return
     */
    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver(){
        SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();
        Properties properties = new Properties();
        properties.setProperty("UnauthorizedException","/errorPage/unAuthorized.html");
        simpleMappingExceptionResolver.setExceptionMappings(properties);
        return simpleMappingExceptionResolver;
    }

    //配置核心安全事务管理器
    @Bean(name = "securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") MyRealm authRealm) {
        System.err.println("--------------恭喜小宋，shiro已经加载成功！----------------");
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        defaultWebSecurityManager.setRealm(authRealm);
        defaultWebSecurityManager.setRememberMeManager(rememberMeManager());
        return defaultWebSecurityManager;
    }
//    配置自定义的权限登录器
    @Bean(name = "authRealm")
    public MyRealm myRealm(){
        MyRealm authRealm = new MyRealm();
        return authRealm;
    }
    @Bean
    public SimpleCookie SimpleCookie(){
        //这个参数是cookie的名称，对应前端的checkbox的name = rememberMe
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        simpleCookie.setHttpOnly(true);
        simpleCookie.setMaxAge(2592000);//30天
        return simpleCookie;
    }
    @Bean
    public CookieRememberMeManager rememberMeManager(){
        CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
        cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUs0FSA3SDFAdag=="));
        cookieRememberMeManager.setCookie(SimpleCookie());
        return cookieRememberMeManager;
    }
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager manager) {
        AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(manager);
        return advisor;
    }
////    整合ShiroDialect：用来整合 shiro thymeleaf
//    @Bean
//    public ShiroDialect getShiroDialect(){
//        return new ShiroDialect();
//    }
}

